package com.yoki.cloud.common.utils.filter;


import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;

/**
 * @author Sky$
 * @Description: TODO
 * @date 2018/2/9$ 11:03$
 */
public class MedianFilter {

    public static Image filter(Image img,
                               final int x, final int y, final int width, final int height) {
        return filter(img, x, y, width, height ,null);
    }

    public static Image filter(Image img,
                               final int x, final int y, final int width, final int height, Integer bind) {
        int[] pixels = new int[width * height];
        try {
            PixelGrabber pg = new PixelGrabber(img, x, y, width, height, pixels, 0, width);
            pg.grabPixels();
        } catch (InterruptedException e3) {
            e3.printStackTrace();
        }
        BufferedImage grayImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        ColorModel cm = ColorModel.getRGBdefault();

        // 取点边长
        int sideLength = 3;
        if (null != bind && bind.intValue() > 1 && bind.intValue() < Math.min(width, height)) {
            sideLength = bind.intValue();
        }
        int cellCount = sideLength * sideLength;
        int[] reds = new int[cellCount];
        int[] greens = new int[cellCount];
        int[] blues = new int[cellCount];


        for (int h = 0; h < height - (sideLength - 1); h++) {
            for (int w = 0; w < width - (sideLength - 1); w++) {

                for (int i = 0; i < sideLength; i++) {
                    for (int j = 0; j < sideLength; j++) {
                        reds[i * sideLength + j] = cm.getRed(pixels[(h + i) * width + w + j]);
                        greens[i * sideLength + j] = cm.getGreen(pixels[(h + i) * width + w + j]);
                        blues[i * sideLength + j] = cm.getBlue(pixels[(h + i) * width + w + j]);
                    }
                }
                //冒泡排序
                for (int j = 0; j < (cellCount - 1); j++) {
                    for (int i = 0; i < ((cellCount - 1) - j); i++) {
                        if (reds[i] > reds[i + 1]) {
                            int temp = reds[i];
                            reds[i] = reds[i + 1];
                            reds[i + 1] = temp;
                        }
                        if (greens[i] > greens[i + 1]) {
                            int temp = greens[i];
                            greens[i] = greens[i + 1];
                            greens[i + 1] = temp;
                        }
                        if (blues[i] > blues[i + 1]) {
                            int temp = blues[i];
                            blues[i] = blues[i + 1];
                            blues[i + 1] = temp;
                        }
                    }
                }
                int medianRed = reds[cellCount / 2];
                int medianGreen = greens[cellCount / 2];
                int medianBlue = blues[cellCount / 2];

                int rgb = 255 << 24 | medianRed << 16 | medianGreen << 8 | medianBlue;
                grayImage.setRGB(w, h, rgb);
            }
        }
        return grayImage;
    }

}
